﻿Imports System.Windows.Forms
Imports System.Drawing.Drawing2D

Public Class FirefoxRenderer : Inherits ToolStripProfessionalRenderer

    Sub New()
        RoundedEdges = False
    End Sub

    Protected Overrides Sub OnRenderToolStripPanelBackground(ByVal e As System.Windows.Forms.ToolStripPanelRenderEventArgs)
        MyBase.OnRenderToolStripPanelBackground(e)
        Dim R = e.ToolStripPanel.Bounds
        If R.Width = 0 Or R.Height = 0 Then Exit Sub
        PaintBackground(e.Graphics, R)
    End Sub

    Protected Overrides Sub OnRenderButtonBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
        PaintButton(e.Graphics, e.Item)
    End Sub

    Protected Overrides Sub OnRenderArrow(ByVal e As System.Windows.Forms.ToolStripArrowRenderEventArgs)
        If e.Item.Pressed Then
            e.ArrowColor = SystemColors.Highlight
            e.ArrowRectangle.Offset(0, 1)
        End If
        MyBase.OnRenderArrow(e)
    End Sub

    Protected Overrides Sub OnRenderDropDownButtonBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
        PaintButton(e.Graphics, e.Item)
    End Sub

    Protected Overrides Sub OnRenderMenuItemBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
        PaintButton(e.Graphics, e.Item, True)
    End Sub

    Protected Overrides Sub OnRenderSplitButtonBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
        PaintButton(e.Graphics, e.Item)
        Dim R = CType(e.Item, ToolStripSplitButton).DropDownButtonBounds
        Dim evt As New ToolStripArrowRenderEventArgs(e.Graphics, e.Item, R, Color.Black, ArrowDirection.Down)
        OnRenderArrow(evt)
        R.Height -= 2
        R.Inflate(0, -1)
        e.Graphics.DrawLine(Color.Black.Opacity(64).Pen, R.Left, R.Top, R.Left, R.Bottom)
        If e.Item.Selected Then e.Graphics.DrawLine(Color.Cyan.Opacity(32).Pen, R.Left, R.Top, R.Left, R.Bottom)
    End Sub

	Protected Overrides Sub OnRenderOverflowButtonBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
		Dim Args As New ToolStripArrowRenderEventArgs(e.Graphics, e.Item, New Rectangle(New Point(0, 0), e.Item.Bounds.Size), Color.Black, ArrowDirection.Down)
		Me.DrawArrow(Args)
		'PaintButton(e.Graphics, e.Item)
	End Sub

    Protected Overrides Sub OnRenderSeparator(ByVal e As System.Windows.Forms.ToolStripSeparatorRenderEventArgs)
        If e.Vertical Then Exit Sub
        MyBase.OnRenderSeparator(e)
    End Sub

    Protected Overrides Sub OnRenderToolStripBorder(ByVal e As System.Windows.Forms.ToolStripRenderEventArgs)
        If Not e.ToolStrip.IsDropDown Then Exit Sub
        Dim R = e.AffectedBounds
        R.Width -= 1
        R.Height -= 1
        e.Graphics.DrawRectangle(Color.Black.Opacity(128).Pen, R)
    End Sub

    Sub PaintButton(ByVal G As Graphics, ByVal Item As ToolStripItem, Optional ByVal Flat As Boolean = False)
        Dim R As New Rectangle(0, 0, Item.Bounds.Width, Item.Bounds.Height)
        If TypeOf Item Is ToolStripMenuItem Then R.Inflate(-1, 0) : R.Offset(1, 0) : R.Width -= 1
        Dim Arc() As Integer = New Integer() {6, 6, 6, 6}
        Dim Pressed As Boolean = Item.Pressed
        Dim Selected As Boolean = Item.Selected
        If TypeOf Item Is ToolStripSplitButton Then
            Dim B = CType(Item, ToolStripSplitButton)
            Pressed = B.ButtonPressed
        ElseIf TypeOf Item Is ToolStripMenuItem Then
            Pressed = False
        End If
        If Not Flat Then
            If Not Item.GetCurrentParent.HasNeighbor(Item, 1) Then Arc(1) = 0 : Arc(2) = 0 : R.Width += 1
            If Not Item.GetCurrentParent.HasNeighbor(Item, -1) Then Arc(0) = 0 : Arc(3) = 0
        End If
        If TypeOf Item Is ToolStripDropDownButton And Item.Tag = "combo" Then
            DrawCombo(G, R, Selected, Pressed, Arc, Flat)
        Else
            Draw(G, R, Selected, Pressed, Arc, Flat)
        End If
    End Sub

    Shared Sub Draw(ByVal G As Graphics, ByVal R As Rectangle, ByVal Selected As Boolean, ByVal Pressed As Boolean, ByVal Arc() As Integer, Optional ByVal Flat As Boolean = False)
        Dim LGB As LinearGradientBrush
        G.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        R.Width -= 1 : R.Height -= 1
        If Pressed Then
            LGB = New Drawing2D.LinearGradientBrush(R, Color.Black.Opacity(0), Color.White.Opacity(64), Drawing2D.LinearGradientMode.Vertical)
            G.DrawRoundRect(New Pen(LGB), R, Arc(0), Arc(1), Arc(2), Arc(3))
        ElseIf Selected Or Not Flat Then
            LGB = New Drawing2D.LinearGradientBrush(R, Color.Black.Opacity(0), Color.Black.Opacity(128), Drawing2D.LinearGradientMode.Vertical)
            G.DrawRoundRect(New Pen(Color.FromArgb(64, Color.Black)), R, Arc(0), Arc(1), Arc(2), Arc(3))
        End If
        LGB = New Drawing2D.LinearGradientBrush(R, Color.Black.Opacity(0), Color.Black.Opacity(128), Drawing2D.LinearGradientMode.Vertical)
        R.Height -= 1
        If Not Flat Then G.DrawRoundRect(New Pen(LGB), R, Arc(0), Arc(1), Arc(2), Arc(3))
        R.Inflate(-1, -1)
        If Pressed Then
            R.Inflate(1, 1)
            Dim RR = R
            Dim v = 96
            If Selected Then
                G.FillRoundRect(Color.Black.Opacity(192).Brush, RR, Arc(0), Arc(1), Arc(2), Arc(3))
                For i = 0 To 5
                    Dim brush = Color.White.Opacity(v).Brush
                    G.FillRoundRect(brush, RR, Arc(0) + i, Arc(1) + i, Arc(2) + i, Arc(3) + i)
                    RR.Inflate(-1, -1)
                    v = v / 1.3
                Next
            Else
                G.FillRoundRect(Color.White.Opacity(192).Brush, RR, Arc(0), Arc(1), Arc(2), Arc(3))
            End If
            'G.FillRoundRect(CB, R, Arc(0), Arc(1), Arc(2), Arc(3))
            G.DrawRoundRect(New Pen(Color.FromArgb(128, Color.Black)), R, Arc(0), Arc(1), Arc(2), Arc(3))
        ElseIf Selected Then
            R.Inflate(1, 1)
            G.DrawRoundRect(Color.Black.Opacity(64).Pen, R, Arc(0), Arc(1), Arc(2), Arc(3))
            G.DrawRoundRect(Color.Cyan.Opacity(64).Pen, R, Arc(0), Arc(1), Arc(2), Arc(3))
            LGB = New Drawing2D.LinearGradientBrush(R, Color.White.Opacity(192), Color.White.Opacity(64), Drawing2D.LinearGradientMode.Vertical)
            G.FillRoundRect(LGB, R, Arc(0), Arc(1), Arc(2), Arc(3))
            LGB = New Drawing2D.LinearGradientBrush(R, Color.White.Opacity(64), Color.White.Opacity(0), Drawing2D.LinearGradientMode.Vertical)
            G.FillRoundRect(LGB, R, Arc(0), Arc(1), Arc(2), Arc(3))
            G.FillRoundRect(Color.Cyan.Opacity(16).Brush, R, Arc(0), Arc(1), Arc(2), Arc(3))
            R.Inflate(-1, -1)
            G.DrawRoundRect(New Pen(Color.FromArgb(32, Color.White)), R, Arc(0), Arc(1), Arc(2), Arc(3))
        ElseIf Not Flat Then
            LGB = New Drawing2D.LinearGradientBrush(R, Color.White.Opacity(192), Color.White.Opacity(0), Drawing2D.LinearGradientMode.Vertical)
            G.FillRoundRect(LGB, R, Arc(0), Arc(1), Arc(2), Arc(3))
            G.DrawRoundRect(New Pen(Color.FromArgb(128, Color.White)), R, Arc(0), Arc(1), Arc(2), Arc(3))
        End If
    End Sub

    Shared Sub DrawCombo(ByVal G As Graphics, ByVal R As Rectangle, ByVal Selected As Boolean, ByVal Pressed As Boolean, ByVal Arc() As Integer, Optional ByVal Flat As Boolean = False)
        Dim LGB As LinearGradientBrush
        G.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        R.Width -= 1 : R.Height -= 1
        'If Pressed Then
        LGB = New Drawing2D.LinearGradientBrush(R, Color.Black.Opacity(0), Color.White.Opacity(64), Drawing2D.LinearGradientMode.Vertical)
        G.DrawRoundRect(New Pen(LGB), R, Arc(0), Arc(1), Arc(2), Arc(3))
        R.Height -= 1
        LGB = New Drawing2D.LinearGradientBrush(R, Color.Black.Opacity(0), Color.Black.Opacity(128), Drawing2D.LinearGradientMode.Vertical)
        If Not Flat Then G.DrawRoundRect(New Pen(LGB), R, Arc(0), Arc(1), Arc(2), Arc(3))
        G.DrawRoundRect(New Pen(Color.FromArgb(128, Color.Black)), R, Arc(0), Arc(1), Arc(2), Arc(3))
        LGB = New Drawing2D.LinearGradientBrush(R, Color.Transparent, Color.White.Opacity(128), Drawing2D.LinearGradientMode.Vertical)
        G.FillRoundRect(LGB, R, Arc(0), Arc(1), Arc(2), Arc(3))
        If Selected Or Pressed Then
            G.FillRoundRect(Color.White.Opacity(128).Brush, R, Arc(0), Arc(1), Arc(2), Arc(3))
        End If
    End Sub

    Shared Sub PaintBackground(ByVal G As Graphics, ByVal R As Rectangle)
        G.FillRectangle(Color.FromArgb(128, 144, 192).Brush, R)
        Dim LGB As New Drawing2D.LinearGradientBrush(R, Color.White.Opacity(224), Color.White.Opacity(144), Drawing2D.LinearGradientMode.Vertical)
        G.FillRectangle(LGB, R)
        G.SmoothingMode = Drawing2D.SmoothingMode.None
        G.PixelOffsetMode = Drawing2D.PixelOffsetMode.None
        G.DrawLine(Color.Black.Opacity(16).Pen, R.Left, R.Bottom - 2, R.Right, R.Bottom - 2)
        G.DrawLine(Color.Black.Opacity(48).Pen, R.Left, R.Bottom - 1, R.Right, R.Bottom - 1)
    End Sub

End Class

Public Class FirefoxToolstrip : Inherits ToolStrip

    Sub New()
        MyBase.New()
        Padding = New Padding(6, 4, 4, 4)
        Renderer = New FirefoxRenderer
        GripStyle = ToolStripGripStyle.Hidden
    End Sub

    Property ButtonPadding As Padding = New Padding(3, 2, 3, 2)

    Protected Overrides Sub OnItemAdded(ByVal e As System.Windows.Forms.ToolStripItemEventArgs)
        MyBase.OnItemAdded(e)
        e.Item.Padding = ButtonPadding
    End Sub

    Property HasBackground As Boolean = True

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
        If Not HasBackground Then Exit Sub
        FirefoxRenderer.PaintBackground(e.Graphics, ClientRectangle)
    End Sub

    Shared Sub ApplyProperties(ToolBar As ToolStrip)
        ToolBar.Renderer = New FirefoxRenderer
        ToolBar.GripStyle = ToolStripGripStyle.Hidden
        For Each Item In ToolBar.Items
            Item.Padding = New Padding(2, 2, 2, 2)
        Next
        ToolBar.Padding = New Padding(4, 2, 2, 2)
    End Sub

End Class

